﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;

using PacketAnalyzer.Data;

namespace PacketAnalyzer.Analyzer
{
    public class ZentecAnalyzer : IAnalyzer
    {
        private static ZentecAnalyzer instance = null;
        private static object syncRoot = new object();

        private System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(51949);

        public static ZentecAnalyzer GetInstance()
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                        instance = new ZentecAnalyzer();
                }
            }

            return instance;
        }

        public ZentecAnalyzer()
        {
        }

        static readonly int newOrderLength = 188;
        static readonly int newOrderReplyLength = newOrderLength + 252;
        static readonly int amendOrderLength = 165;
        static readonly int amendOrderReplyLength = amendOrderLength + 248;
        static readonly int cancelOrderLength = 149;
        static readonly int cancelOrderReplyLength = cancelOrderLength + 184;
        static readonly int executionLength = 1088;
        //static readonly int executionLength = 1080;

        public List<PacketData> Analyze(string packet)
        {
            List<PacketData> r = new List<PacketData>();
            byte[] packetBytes = encoding.GetBytes(packet);

            string serviceCode = "";
            
            bool containsHeader = (packet[0] == 0x02);

            PacketData headerPacketData = null;

            if (containsHeader)
            {
                headerPacketData = ZentecHeaderAnalyzer.GetInstance().Analyze(packet);

                if (!headerPacketData.Get("전문코드").Equals("DATA"))
                {
                    r.Add(headerPacketData);

                    return r;
                }

                serviceCode = headerPacketData.Get("서비스코드");
            }

            // ToDo: 레코드 여러개 있는 경우 처리

            int headerLength = (headerPacketData != null) ? headerPacketData.Length : 0;
            int bodyLength = packetBytes.Length - headerLength;

            PacketData body = null;

            if (serviceCode.Equals("SONAT000") || serviceCode.Equals("SONAT080") || (bodyLength % newOrderReplyLength == 0))
            {
                // 신규 주문 Reply
                body = AnalyzeNewOrderReply(packet.Substring(headerLength));
            }
            else if (serviceCode.Equals("SONAT000") || serviceCode.Equals("SONAT080") || (bodyLength % newOrderLength == 0))
            {
                // 신규 주문
                body = AnalyzeNewOrder(packet.Substring(headerLength));
            }
            else if (serviceCode.Equals("SONAT001") || serviceCode.Equals("SONAT081") || (bodyLength % amendOrderReplyLength == 0))
            {
                // 정정 주문 Reply
                body = AnalyzeAmendOrderReply(packet.Substring(headerLength));
            }
            else if (serviceCode.Equals("SONAT001") || serviceCode.Equals("SONAT081") || (bodyLength % amendOrderLength == 0))
            {
                // 정정 주문
                body = AnalyzeAmendOrder(packet.Substring(headerLength));
            }
            else if (serviceCode.Equals("SONAT002") || serviceCode.Equals("SONAT082") || (bodyLength % cancelOrderReplyLength == 0))
            {
                // 취소
                body = AnalyzeCancelOrderReply(packet.Substring(headerLength));
            }
            else if (serviceCode.Equals("SONAT002") || serviceCode.Equals("SONAT082") || (bodyLength % cancelOrderLength == 0))
            {
                // 취소
                body = AnalyzeCancelOrder(packet.Substring(headerLength));
            }
            else if (serviceCode.IndexOf("SONAS") >= 0 || (bodyLength >= executionLength))
            {
                // 체결
                body = AnalyzeExecution(packet.Substring(headerLength));
            }

            if (headerPacketData != null && body != null)
            {
                r.Add(headerPacketData.Merge(body));

                return r;
            }

            if (body != null)
            {
                r.Add(body);

                return r;
            }

            return null;
        }

        /// <summary>
        /// 주문 패킷 분석
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        public PacketData AnalyzeNewOrder(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            packetData.Add("주문종류", "신규주문");
            pos = packetData.AddResult(packet, "레코드갯수", PacketData.TYPE_NUMERIC, 5, pos, null);
            pos = packetData.AddResult(packet, "계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "입력비밀번호", 8, pos, null);
            pos = packetData.AddResult(packet, "종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "주문수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "주문가", PacketData.TYPE_NUMERIC, 13, pos, null);
            pos = packetData.AddResult(packet, "매매구분", 1, pos, new Dictionary<string, string> { {"1", "매도"}, {"2", "매수"} });
            pos = packetData.AddResult(packet, "호가유형코드", 2, pos, new Dictionary<string, string> { { "00", "지정가" }, {"03", "시장가"}, {"05", "조건부지정가"}, {"06", "최유리지정가"}, {"07", "최우선지정가"}, {"09", "자사주"}, {"41", "부분충족(프리보드)"}, {"42", "전량충족(프리보드)"}, {"61", "장개시전시간외"}, {"67", "장개시전시간외대량"}, {"68", "장개시전시간외바스켓"}, {"71", "신고대량전장시가"}, {"73", "신고대량종가"}, {"77", "장중대량"}, {"78", "장중바스켓"}, {"81", "시간외종가"}, {"82", "시간외단일가"}, {"87", "시간외대량"}, {"88", "바스켓주문"}, {"89", "시간외자사주"}, {"91", "자사주스톡옵션"} });
            pos = packetData.AddResult(packet, "프로그램호가유형코드", 2, pos, new Dictionary<string, string> { { "00", "일반" }, {"01", "차익거래"}, {"02", "비차익거래"}, {"03", "주식차익"}, {"04", "ETF차익"}, {"05", "ETF기타"}, {"06", "ETF차익비차익"}, {"07", "ETF설정비차익"}, {"08", "DR차익"}, {"09", "헤지거래를 위한 공매도"}, {"10", "ETF LP의 헷지거래"}, {"11", "주식선물옵션 LP의 헷지거래"}, {"12", "장외파생상품의 헷지거래"} });
            pos = packetData.AddResult(packet, "공매도가능여부", 1, pos, new Dictionary<string, string> { { "0", "공매도불가" }, {"1", "공매도가능"} });
            pos = packetData.AddResult(packet, "공매도호가구분", 1, pos, new Dictionary<string, string> { { "0", "공매도아님" }, {"1", "차입주식매도"}, {"2", "기타공매도"} });
            pos = packetData.AddResult(packet, "통신매체코드", 2, pos, null);
            pos = packetData.AddResult(packet, "신용거래코드", 3, pos, new Dictionary<string, string> { { "000", "보통" }, {"001", "유통융자신규"}, {"003", "자기융자신규"}, {"005", "유통대주신규"}, {"007", "자기대주신규"}, {"101", "유통융자상환"}, {"103", "자기융자상환"}, {"105", "유통대주상환"}, {"107", "자기대주상환"}, {"180", "예탁담보대출상환(신용)"} });
            pos = packetData.AddResult(packet, "대출일", 8, pos, null);
            pos = packetData.AddResult(packet, "회원번호", 3, pos, null);
            pos = packetData.AddResult(packet, "주문조건구분", 1, pos, new Dictionary<string, string> { { "0", "없음" }, {"1", "IOC"}, {"2", "FOK"} });
            pos = packetData.AddResult(packet, "전략코드", 6, pos, null);
            pos = packetData.AddResult(packet, "그룹ID", 20, pos, null);
            pos = packetData.AddResult(packet, "주문회차", 10, pos, null);
            pos = packetData.AddResult(packet, "포트폴리오번호", 10, pos, null);
            pos = packetData.AddResult(packet, "바스켓번호", 10, pos, null);
            pos = packetData.AddResult(packet, "트렌치번호", 10, pos, null);
            pos = packetData.AddResult(packet, "아이템번호", 10, pos, null);
            pos = packetData.AddResult(packet, "운용지시번호", 12, pos, null);
            pos = packetData.AddResult(packet, "유동성공급자여부", 1, pos, new Dictionary<string, string> { { "0", "유동성공급자 아님" }, {"1", "유동성공급자호가"} });
            pos = packetData.AddResult(packet, "반대매매구분", 1, pos, new Dictionary<string, string> { { "0", "반대매매아님" }, {"1", "반대매매"} });

            return packetData;
        }


        /// <summary>
        /// 주문 패킷 분석
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        public PacketData AnalyzeNewOrderReply(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            packetData.Add("주문종류", "신규주문Reply");
            pos = packetData.AddResult(packet, "레코드갯수", PacketData.TYPE_NUMERIC, 5, pos, null);
            pos = packetData.AddResult(packet, "계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "입력비밀번호", 8, pos, null);
            pos = packetData.AddResult(packet, "종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "주문수량", PacketData.TYPE_NUMERIC, 15, pos, null);
            pos = packetData.AddResult(packet, "주문가", PacketData.TYPE_NUMERIC, 13, pos, null);
            pos = packetData.AddResult(packet, "매매구분", 1, pos, new Dictionary<string, string> { { "1", "매도" }, { "2", "매수" } });
            pos = packetData.AddResult(packet, "호가유형코드", 2, pos, new Dictionary<string, string> { { "00", "지정가" }, { "03", "시장가" }, { "05", "조건부지정가" }, { "06", "최유리지정가" }, { "07", "최우선지정가" }, { "09", "자사주" }, { "41", "부분충족(프리보드)" }, { "42", "전량충족(프리보드)" }, { "61", "장개시전시간외" }, { "67", "장개시전시간외대량" }, { "68", "장개시전시간외바스켓" }, { "71", "신고대량전장시가" }, { "73", "신고대량종가" }, { "77", "장중대량" }, { "78", "장중바스켓" }, { "81", "시간외종가" }, { "82", "시간외단일가" }, { "87", "시간외대량" }, { "88", "바스켓주문" }, { "89", "시간외자사주" }, { "91", "자사주스톡옵션" } });
            pos = packetData.AddResult(packet, "프로그램호가유형코드", 2, pos, new Dictionary<string, string> { { "00", "일반" }, { "01", "차익거래" }, { "02", "비차익거래" }, { "03", "주식차익" }, { "04", "ETF차익" }, { "05", "ETF기타" }, { "06", "ETF차익비차익" }, { "07", "ETF설정비차익" }, { "08", "DR차익" }, { "09", "헤지거래를 위한 공매도" }, { "10", "ETF LP의 헷지거래" }, { "11", "주식선물옵션 LP의 헷지거래" }, { "12", "장외파생상품의 헷지거래" } });
            pos = packetData.AddResult(packet, "공매도가능여부", 1, pos, new Dictionary<string, string> { { "0", "공매도불가" }, { "1", "공매도가능" } });
            pos = packetData.AddResult(packet, "공매도호가구분", 1, pos, new Dictionary<string, string> { { "0", "공매도아님" }, { "1", "차입주식매도" }, { "2", "기타공매도" } });
            pos = packetData.AddResult(packet, "통신매체코드", 2, pos, null);
            pos = packetData.AddResult(packet, "신용거래코드", 3, pos, new Dictionary<string, string> { { "000", "보통" }, { "001", "유통융자신규" }, { "003", "자기융자신규" }, { "005", "유통대주신규" }, { "007", "자기대주신규" }, { "101", "유통융자상환" }, { "103", "자기융자상환" }, { "105", "유통대주상환" }, { "107", "자기대주상환" }, { "180", "예탁담보대출상환(신용)" } });
            pos = packetData.AddResult(packet, "대출일", 8, pos, null);
            pos = packetData.AddResult(packet, "회원번호", 3, pos, null);
            pos = packetData.AddResult(packet, "주문조건구분", 1, pos, new Dictionary<string, string> { { "0", "없음" }, { "1", "IOC" }, { "2", "FOK" } });
            pos = packetData.AddResult(packet, "전략코드", 6, pos, null);
            pos = packetData.AddResult(packet, "그룹ID", 20, pos, null);
            pos = packetData.AddResult(packet, "주문회차", 10, pos, null);
            pos = packetData.AddResult(packet, "포트폴리오번호", 10, pos, null);
            pos = packetData.AddResult(packet, "바스켓번호", 10, pos, null);
            pos = packetData.AddResult(packet, "트렌치번호", 10, pos, null);
            pos = packetData.AddResult(packet, "아이템번호", 10, pos, null);
            pos = packetData.AddResult(packet, "운용지시번호", 12, pos, null);
            pos = packetData.AddResult(packet, "유동성공급자여부", 1, pos, new Dictionary<string, string> { { "0", "유동성공급자 아님" }, { "1", "유동성공급자호가" } });
            pos = packetData.AddResult(packet, "반대매매구분", 1, pos, new Dictionary<string, string> { { "0", "반대매매아님" }, { "1", "반대매매" } });
            pos = packetData.AddResult(packet, "레코드갯수", 5, pos, null);
            pos = packetData.AddResult(packet, "주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "주문시각", 9, pos, null);
            pos = packetData.AddResult(packet, "주문시장코드", 2, pos, null);
            pos = packetData.AddResult(packet, "주문유형코드", 2, pos, null);
            pos = packetData.AddResult(packet, "단축종목번호", 9, pos, null);
            pos = packetData.AddResult(packet, "관리사원번호", 9, pos, null);
            pos = packetData.AddResult(packet, "주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "예비주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "반대매매일련번호", 10, pos, null);
            pos = packetData.AddResult(packet, "예약주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "실물주문수량", 16, pos, null);
            pos = packetData.AddResult(packet, "재사용주문수량", 16, pos, null);
            pos = packetData.AddResult(packet, "현금주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "대용주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "재사용주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "계좌명", 40, pos, null);
            pos = packetData.AddResult(packet, "종목명", 40, pos, null);

            return packetData;
        }


        public PacketData AnalyzeAmendOrder(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            packetData.Add("주문종류", "정정주문");
            pos = packetData.AddResult(packet, "레코드갯수", PacketData.TYPE_NUMERIC, 5, pos, null);
            pos = packetData.AddResult(packet, "원주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "입력비밀번호", 8, pos, null);
            pos = packetData.AddResult(packet, "종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "주문수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "호가유형코드", 2, pos, new Dictionary<string, string> { { "00", "지정가" }, { "03", "시장가" }, { "05", "조건부지정가" }, { "06", "최유리지정가" }, { "07", "최우선지정가" }, { "09", "자사주" }, { "41", "부분충족(프리보드)" }, { "42", "전량충족(프리보드)" }, { "61", "장개시전시간외" }, { "67", "장개시전시간외대량" }, { "68", "장개시전시간외바스켓" }, { "71", "신고대량전장시가" }, { "73", "신고대량종가" }, { "77", "장중대량" }, { "78", "장중바스켓" }, { "81", "시간외종가" }, { "82", "시간외단일가" }, { "87", "시간외대량" }, { "88", "바스켓주문" }, { "89", "시간외자사주" }, { "91", "자사주스톡옵션" } });
            pos = packetData.AddResult(packet, "주문조건구분", 1, pos, new Dictionary<string, string> { { "0", "없음" }, { "1", "IOC" }, { "2", "FOK" } });
            pos = packetData.AddResult(packet, "주문가", PacketData.TYPE_NUMERIC, 13, pos, null);
            pos = packetData.AddResult(packet, "통신매체코드", 2, pos, null);
            pos = packetData.AddResult(packet, "전략코드", 6, pos, null);
            pos = packetData.AddResult(packet, "그룹ID", 20, pos, null);
            pos = packetData.AddResult(packet, "주문회차", 10, pos, null);
            pos = packetData.AddResult(packet, "포트폴리오번호", 10, pos, null);
            pos = packetData.AddResult(packet, "바스켓번호", 10, pos, null);
            pos = packetData.AddResult(packet, "트렌치번호", 10, pos, null);
            pos = packetData.AddResult(packet, "아이템번호", 10, pos, null);
            pos = packetData.AddResult(packet, "레코드갯수", 5, pos, null);
            pos = packetData.AddResult(packet, "주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "모주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "주문시각", 9, pos, null);
            pos = packetData.AddResult(packet, "주문시장코드", 2, pos, null);
            pos = packetData.AddResult(packet, "주문유형코드", 2, pos, null);
            pos = packetData.AddResult(packet, "단축종목번호", 9, pos, null);
            pos = packetData.AddResult(packet, "프로그램호가유형코드", 2, pos, null);
            pos = packetData.AddResult(packet, "공매도호가구분", 1, pos, null);
            pos = packetData.AddResult(packet, "공매도가능여부", 1, pos, null);
            pos = packetData.AddResult(packet, "신용거래코드", 3, pos, null);
            pos = packetData.AddResult(packet, "대출일", 8, pos, null);
            pos = packetData.AddResult(packet, "반대매매주문구분", 1, pos, null);
            pos = packetData.AddResult(packet, "유동성공급자여부", 1, pos, null);
            pos = packetData.AddResult(packet, "관리사원번호", 9, pos, null);
            pos = packetData.AddResult(packet, "주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "매매구분", 1, pos, null);
            pos = packetData.AddResult(packet, "예비주문번호", 01, pos, null);
            pos = packetData.AddResult(packet, "반대매매일련번호", 10, pos, null);
            pos = packetData.AddResult(packet, "예약주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "현금주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "대용주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "재사용주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "계좌명", 40, pos, null);
            pos = packetData.AddResult(packet, "종목명", 40, pos, null);

           
            return packetData;
        }


        public PacketData AnalyzeAmendOrderReply(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            packetData.Add("주문종류", "정정주문Reply");
            pos = packetData.AddResult(packet, "레코드갯수Reply", PacketData.TYPE_NUMERIC, 5, pos, null);
            pos = packetData.AddResult(packet, "원주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "입력비밀번호", 8, pos, null);
            pos = packetData.AddResult(packet, "종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "주문수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "호가유형코드", 2, pos, new Dictionary<string, string> { { "00", "지정가" }, { "03", "시장가" }, { "05", "조건부지정가" }, { "06", "최유리지정가" }, { "07", "최우선지정가" }, { "09", "자사주" }, { "41", "부분충족(프리보드)" }, { "42", "전량충족(프리보드)" }, { "61", "장개시전시간외" }, { "67", "장개시전시간외대량" }, { "68", "장개시전시간외바스켓" }, { "71", "신고대량전장시가" }, { "73", "신고대량종가" }, { "77", "장중대량" }, { "78", "장중바스켓" }, { "81", "시간외종가" }, { "82", "시간외단일가" }, { "87", "시간외대량" }, { "88", "바스켓주문" }, { "89", "시간외자사주" }, { "91", "자사주스톡옵션" } });
            pos = packetData.AddResult(packet, "주문조건구분", 1, pos, new Dictionary<string, string> { { "0", "없음" }, { "1", "IOC" }, { "2", "FOK" } });
            pos = packetData.AddResult(packet, "주문가", 13, pos, null);
            pos = packetData.AddResult(packet, "통신매체코드", 2, pos, null);
            pos = packetData.AddResult(packet, "전략코드", 6, pos, null);
            pos = packetData.AddResult(packet, "그룹ID", 20, pos, null);
            pos = packetData.AddResult(packet, "주문회차", 10, pos, null);
            pos = packetData.AddResult(packet, "포트폴리오번호", 10, pos, null);
            pos = packetData.AddResult(packet, "바스켓번호", 10, pos, null);
            pos = packetData.AddResult(packet, "트렌치번호", 10, pos, null);
            pos = packetData.AddResult(packet, "아이템번호", 10, pos, null);

            return packetData;
        }


        public PacketData AnalyzeCancelOrder(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            packetData.Add("주문종류", "취소주문");
            pos = packetData.AddResult(packet, "레코드갯수", PacketData.TYPE_NUMERIC, 5, pos, null);
            pos = packetData.AddResult(packet, "원주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "입력비밀번호", 8, pos, null);
            pos = packetData.AddResult(packet, "종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "주문수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "통신매체코드", 2, pos, null);
            pos = packetData.AddResult(packet, "그룹ID", 20, pos, null);
            pos = packetData.AddResult(packet, "전략코드", 6, pos, null);
            pos = packetData.AddResult(packet, "주문회차", 10, pos, null);
            pos = packetData.AddResult(packet, "포트폴리오번호", 10, pos, null);
            pos = packetData.AddResult(packet, "바스켓번호", 10, pos, null);
            pos = packetData.AddResult(packet, "트렌치번호", 10, pos, null);
            pos = packetData.AddResult(packet, "아이템번호", 10, pos, null);

            return packetData;
        }


        public PacketData AnalyzeCancelOrderReply(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            packetData.Add("주문종류", "취소주문Reply");
            pos = packetData.AddResult(packet, "레코드갯수Reply", PacketData.TYPE_NUMERIC, 5, pos, null);
            pos = packetData.AddResult(packet, "원주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "입력비밀번호", 8, pos, null);
            pos = packetData.AddResult(packet, "종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "주문수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "통신매체코드", 2, pos, null);
            pos = packetData.AddResult(packet, "그룹ID", 20, pos, null);
            pos = packetData.AddResult(packet, "전략코드", 6, pos, null);
            pos = packetData.AddResult(packet, "주문회차", 10, pos, null);
            pos = packetData.AddResult(packet, "포트폴리오번호", 10, pos, null);
            pos = packetData.AddResult(packet, "바스켓번호", 10, pos, null);
            pos = packetData.AddResult(packet, "트렌치번호", 10, pos, null);
            pos = packetData.AddResult(packet, "아이템번호", 10, pos, null);
            pos = packetData.AddResult(packet, "레코드갯수", 5, pos, null);
            pos = packetData.AddResult(packet, "주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "모주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "주문시각", 9, pos, null);
            pos = packetData.AddResult(packet, "주문시장코드", 2, pos, null);
            pos = packetData.AddResult(packet, "주문유형코드", 2, pos, null);
            pos = packetData.AddResult(packet, "단축종목번호", 9, pos, null);
            pos = packetData.AddResult(packet, "프로그램호가유형코드", 2, pos, null);
            pos = packetData.AddResult(packet, "공매도호가구분", 1, pos, null);
            pos = packetData.AddResult(packet, "공매도가능여부", 1, pos, null);
            pos = packetData.AddResult(packet, "신용거래코드", 3, pos, null);
            pos = packetData.AddResult(packet, "대출일", 8, pos, null);
            pos = packetData.AddResult(packet, "반대매매주문구분", 1, pos, null);
            pos = packetData.AddResult(packet, "유동성공급자여부", 1, pos, null);
            pos = packetData.AddResult(packet, "관리사원번호", 9, pos, null);
            pos = packetData.AddResult(packet, "매매구분", 1, pos, null);
            pos = packetData.AddResult(packet, "예비주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "반대매매일련번호", 10, pos, null);
            pos = packetData.AddResult(packet, "예약주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "계좌명", 40, pos, null);
            pos = packetData.AddResult(packet, "종목명", 40, pos, null);

            return packetData;
        }

        /// <summary>
        /// 체결 패킷 분석
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        public PacketData AnalyzeExecution(string packet)
        {
            PacketData packetData = new PacketData();

            int pos = 0;

            pos = packetData.AddResult(packet, "주문체결유형코드", 2, pos, new Dictionary<string, string>{ {"01", "주문"}, {"02", "정정"}, {"03", "취소"}, {"11", "체결"}, {"12", "정정확인"}, {"13", "취소확인"}, {"14", "거부"}, {"15", "거부"}, {"16", "거부"} });
            pos = packetData.AddResult(packet, "주문시장코드", 2, pos, new Dictionary<string, string> { { "00", "비상장" }, {"10", "KSE"}, {"11", "채권"}, {"19", "장외시장"}, {"20", "KOSDAQ"}, {"30", "OTCBB"}, {"61", "동경거래소"}, {"62", "JASDAQ"} });
            pos = packetData.AddResult(packet, "주문유형코드", 2, pos, new Dictionary<string, string>{ {"01", "현금매도"}, {"02", "현금매수"}, {"03", "신용매도"}, {"04", "신용매수"}, {"05", "저축매도"}, {"06", "저축매수"}, {"07", "상품매도(대차)"}, {"09", "상품매도"}, {"10", "상품매수"}, {"11", "선물대용매도(일반)"}, {"12", "선물대용매도(반대)"}, {"13", "현금매도(프)"}, {"14", "현금매수(프)"}, {"15", "현금매수(유가)"}, {"16", "현금매수(정리)"}, {"17", "상품매도(대차.프)"}, {"19", "상품매도(프)"}, {"20", "상품매수(프)"} });
            pos = packetData.AddResult(packet, "관리지점번호", 3, pos, null);
            pos = packetData.AddResult(packet, "계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "계좌명", 40, pos, null);
            pos = packetData.AddResult(packet, "종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "종목명", 40, pos, null);
            pos = packetData.AddResult(packet, "주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "원주문번호", 10, pos, null);
            pos = packetData.AddResult(packet, "체결번호", 10, pos, null);
            pos = packetData.AddResult(packet, "주문수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "주문가격", PacketData.TYPE_NUMERIC, 13, pos, null);
            pos = packetData.AddResult(packet, "체결수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "체결가격", PacketData.TYPE_NUMERIC, 13, pos, null);
            pos = packetData.AddResult(packet, "정정확인수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "정정확인가격", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "취소확인수량", PacketData.TYPE_NUMERIC, 16, pos, null);
            pos = packetData.AddResult(packet, "거부수량", 16, pos, null);
            pos = packetData.AddResult(packet, "주문처리유형코드", 4, pos, null);
            pos = packetData.AddResult(packet, "복수주문일련번호", 10, pos, null);
            pos = packetData.AddResult(packet, "주문조건", 1, pos, new Dictionary<string, string> { { "0", "없음" }, {"1", "IOC"}, {"2", "FOK"} });
            pos = packetData.AddResult(packet, "호가유형코드", 2, pos, new Dictionary<string, string> { { "00", "지정가" }, {"03", "시장가"}, {"05", "조건부지정가"}, {"06", "최유리지정가"}, {"07", "최우선지정가"}, {"09", "자사주"}, {"41", "부분충족(프리보드)"}, {"42", "전량충족(프리보드)"}, {"61", "장개시전시간외"}, {"67", "장개시전시간외대량"}, {"68", "장개시전시간외바스켓"}, {"71", "신고대량전장시가"}, {"73", "신고대량종가"}, {"78", "장중바스켓"}, {"81", "시간외종가"}, {"82", "시간외단일가"}, {"88", "바스켓주문"}, {"89", "시간외자사주"}, {"91", "자사주스톡옵션"} });
            pos = packetData.AddResult(packet, "비저축체결수량", 16, pos, null);
            pos = packetData.AddResult(packet, "단축종목번호", 9, pos, null);
            pos = packetData.AddResult(packet, "운용지시번호", 12, pos, null);
            pos = packetData.AddResult(packet, "반대매매주문구분", 1, pos, null);
            pos = packetData.AddResult(packet, "미체결수량(주문)", 16, pos, null);
            pos = packetData.AddResult(packet, "원주문미체결수량", 16, pos, null);
            pos = packetData.AddResult(packet, "원주문정정수량", 16, pos, null);
            pos = packetData.AddResult(packet, "원주문취소수량", 16, pos, null);
            pos = packetData.AddResult(packet, "주문평균체결가격", 13, pos, null);
            pos = packetData.AddResult(packet, "주문금액", 16, pos, null);
            pos = packetData.AddResult(packet, "표준종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "전표준종목번호", 12, pos, null);
            pos = packetData.AddResult(packet, "매매구분", 1, pos, new Dictionary<string, string> { { "1", "매도" }, {"2", "매수"} });
            pos = packetData.AddResult(packet, "주문거래유형코드", 2, pos, null);
            pos = packetData.AddResult(packet, "신용거래코드", 3, pos, new Dictionary<string, string> { { "000", "보통" }, {"001", "유통융자신규"}, {"003", "자기융자신규"}, {"005", "유통대주신규"}, {"007", "자기대주신규"}, {"070", "매도대금담보대출신규"}, {"080", "예탁자산담보대출신규"}, {"082", "예탁자산담보대출신규(채권)"}, {"101", "유통융자상환"}, {"103", "자기융자상환"}, {"105", "유통대주상환"}, {"107", "자기대주상환"}, {"180", "예탁담보대출상환(신용)"} });
            pos = packetData.AddResult(packet, "수수료합산코드", 2, pos, null);
            pos = packetData.AddResult(packet, "통신매체코드", 2, pos, null);
            pos = packetData.AddResult(packet, "대출일", 8, pos, null);
            pos = packetData.AddResult(packet, "회원/비회원사번호", 3, pos, null);
            pos = packetData.AddResult(packet, "주문계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "집계지점번호", 3, pos, null);
            pos = packetData.AddResult(packet, "관리사원번호", 9, pos, null);
            pos = packetData.AddResult(packet, "선물연계지점번호", 3, pos, null);
            pos = packetData.AddResult(packet, "선물연계계좌번호", 20, pos, null);
            pos = packetData.AddResult(packet, "선물시장구분", 1, pos, new Dictionary<string, string> { { "0", "KOSPI" }, {"1", "KOFEX"} });
            pos = packetData.AddResult(packet, "등록시장코드", 2, pos, null);
            pos = packetData.AddResult(packet, "현금증거금률", 7, pos, null);
            pos = packetData.AddResult(packet, "대용증거금률", 9, pos, null);
            pos = packetData.AddResult(packet, "현금체결금액", 16, pos, null);
            pos = packetData.AddResult(packet, "대용체결금액", 16, pos, null);
            pos = packetData.AddResult(packet, "수수료체결금액", 16, pos, null);
            pos = packetData.AddResult(packet, "신용담보체결금액", 16, pos, null);
            pos = packetData.AddResult(packet, "신용체결금액", 16, pos, null);
            pos = packetData.AddResult(packet, "전일재사용체결금액", 16, pos, null);
            pos = packetData.AddResult(packet, "금일재사용체결금액", 16, pos, null);
            pos = packetData.AddResult(packet, "실물체결수량", 16, pos, null);
            pos = packetData.AddResult(packet, "공매도체결수량", 16, pos, null);
            pos = packetData.AddResult(packet, "전략코드", 6, pos, null);
            pos = packetData.AddResult(packet, "그룹ID", 20, pos, null);
            pos = packetData.AddResult(packet, "주문회차", 10, pos, null);
            pos = packetData.AddResult(packet, "포트폴리오번호", 10, pos, null);
            pos = packetData.AddResult(packet, "바스켓번호", 10, pos, null);
            pos = packetData.AddResult(packet, "트렌치번호", 10, pos, null);
            pos = packetData.AddResult(packet, "아이템번호", 10, pos, null);
            pos = packetData.AddResult(packet, "주문자ID", 16, pos, null);
            pos = packetData.AddResult(packet, "차입관리여부", 1, pos, null);
            pos = packetData.AddResult(packet, "외국인고유번호", 6, pos, null);
            pos = packetData.AddResult(packet, "거래세징수구분", 1, pos, null);
            pos = packetData.AddResult(packet, "유동성공급자구분", 1, pos, new Dictionary<string, string> { { "0", "해당없음" }, {"1", "유동성공급자"} });
            pos = packetData.AddResult(packet, "체결시각", 9, pos, null);
            pos = packetData.AddResult(packet, "거래소수신체결시각", 9, pos, null);
            pos = packetData.AddResult(packet, "잔여대출금액", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-잔고수량", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-실물가능수량", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-재사용가능수량(매도)", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-변동수량", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-잔고수량(D2)", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-매도주문가능수량", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-미체결매도주문수량", 16, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-평균매입가", 13, pos, null);
            pos = packetData.AddResult(packet, "*주식잔고-매입금액", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-예수금", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-대용금", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-위탁증거금현금", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-위탁증거금대용", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-신용담보재사용금", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-주문가능현금", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-주문가능대용", 16, pos, null);
            pos = packetData.AddResult(packet, "*예수금잔고-재사용가능금액", 16, pos, null);

            return packetData;
        }

        public PacketData AnalyzeOrder(string packet)
        {
            throw new NotImplementedException();
        }

        public PacketData AnalyzeConfirm(string packet)
        {
            throw new NotImplementedException();
        }

        public string GetRejectDescription(string rejectCode)
        {
            throw new NotImplementedException();
        }
    }
}
